package cn.fancylab.template.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.logging.log4j.Logger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Service;

import cn.fancylab.dao.Dao;
import cn.fancylab.model.BaseObject;
import cn.fancylab.service.impl.DaoServiceImpl;
import cn.fancylab.template.service.BaseAppService;
import cn.fancylab.util.LoggerUtils;

@Service("baseAppService")
public class BaseAppServiceImpl extends DaoServiceImpl implements BaseAppService {
	protected final transient Logger dbLogger = LoggerUtils.getLogger(getClass());

	@Autowired
	@Qualifier("baseDao")
	private Dao baseDao;

	@Autowired
	@Qualifier("hibernateTemplate")
	private HibernateTemplate hibernateTemplate;

	public <T extends BaseObject> T getObjectByProperty(Class<T> clazz, Map<String, Object> map) {
		DetachedCriteria query = DetachedCriteria.forClass(clazz);
		Set<String> keyset = map.keySet();
		for (String key : keyset) {
			if (null != map.get(key)) {
				query.add(Restrictions.eq(key, map.get(key)));
			}
		}
		List result = hibernateTemplate.findByCriteria(query);
		if (result.isEmpty()) {
			return null;
		}
		if (result.size() > 1) {
			throw new IllegalStateException("非唯一信息查询错误，返回多个对象。");
		}
		return (T) result.get(0);
	}

	public <T extends BaseObject> List<T> getObjectListByProperty(Class<T> clazz, Map<String, Object> map) {
		DetachedCriteria query = DetachedCriteria.forClass(clazz);
		Set<String> keyset = map.keySet();
		for (String key : keyset) {
			if (null != map.get(key)) {
				query.add(Restrictions.eq(key, map.get(key)));
			}
		}
		List result = hibernateTemplate.findByCriteria(query);
		if (result.isEmpty()) {
			return null;
		}
		return result;
	}

	public <T extends BaseObject> int getObjectCountByProperty(Class<T> clazz, Map<String, Object> map) {
		DetachedCriteria query = DetachedCriteria.forClass(clazz);
		query.setProjection(Projections.rowCount());
		Set<String> keyset = map.keySet();
		for (String key : keyset) {
			if (null != map.get(key)) {
				query.add(Restrictions.eq(key, map.get(key)));
			}
		}
		List result = hibernateTemplate.findByCriteria(query);
		if (result.isEmpty()) {
			return 0;
		}
		return Integer.parseInt("" + result.get(0));
	}
}
